#include "Mouse.hpp"

namespace ge {

//----------------------------------------------------------------------------//
// Mouse
//----------------------------------------------------------------------------//

//----------------------------------------------------------------------------//
Mouse::Mouse( void )
{
     m_recursion_depth = 0;
}
//----------------------------------------------------------------------------//
Mouse::~Mouse( void )
{

}
//----------------------------------------------------------------------------//
void Mouse::_AddObserver( Observer* _observer )
{
     if( _observer ) Instance().m_observers.Append( _observer );
}
//----------------------------------------------------------------------------//
void Mouse::_RemoveObserver( Observer* _observer )
{
     if( _observer )
     {
          Observers::Iterator _iter = Instance().m_observers.Search( _observer );
          if( _iter )
          {
               if( Instance().m_recursion_depth == 0 ) Instance().m_observers.Remove( _iter );
               else *_iter = 0;
          }
     }
}
//----------------------------------------------------------------------------//
void Mouse::_RemoveNullObservers( void )
{
     if( m_recursion_depth == 0 )
     {
          for( Observers::Iterator i = m_observers.First(); i; )
          {
               if( *i == 0 ) i = m_observers.Remove( i );
               else ++ i;
          }
     }
}
//----------------------------------------------------------------------------//
void Mouse::_OnEvent_Button( Button _button, uint _action )
{
     if( m_recursion_depth < MaxRecursionDepth )
     {
          ++ m_recursion_depth;
          uint _notified = 0;

          try 
          {
               for( Observers::Iterator i = m_observers.First(); i; ++ i )
               {
                    if( *i )
                    {
                         ++ _notified;
                         i -> Get() -> OnButtonEvent( _button, _action ); 
                    }
               }
          }
          catch( ... )
          {
               -- m_recursion_depth;
               throw;
          }

          -- m_recursion_depth;
          if( m_recursion_depth == 0 && _notified < m_observers.Size() ) _RemoveNullObservers();
     }
}
//----------------------------------------------------------------------------//

} // namespace ge
